package client

import (
	"net/rpc"

	"learngo/crawler/engine"
	"learngo/crawler_distributed/config"
	"learngo/crawler_distributed/worker"
)

//实现engine.Processor接口
func CreateProcessor(clientChan chan *rpc.Client) engine.Processor {

	//在main.go中调用e.Run(engine.Request{...}.#createWorker时传入
	//因为远程调用不能传函数，因此这里需要engine.Processor转换下
	return func(req engine.Request) (engine.ParserResult, error) {

		//将engine.Request转换成字符串格式(Request)，以便远程调用
		sReq := worker.SerializeRequest(req)

		var sResult worker.ParseResult

		c := <-clientChan
		//远程调用crawler_distributed/worker/rpc.go#Process
		//得到远程调用结果sResult后，需要反序列化成对应的parser
		//反序列的逻辑是根据名字匹配parser的名字
		//服务端(被调用方)反序列化的原因是，需要调用具体的Parser去解析页面
		//客户端(调用方)反序列化的原因是，需要调用具体的Parser生成下个Request
		err := c.Call(config.CrawlServiceRpc,
			sReq, &sResult)

		if err != nil {
			return engine.ParserResult{}, err
		}
		//这里反序列返回的结果，原因是
		//根据返回的string,需要重新封装一个Request,然后远程调用，以这个Reuqest作为参数
		// 而这个request中封装了Parser的具体类型
		//因而需要根据远程返回的string中的名字，构造Parser的具体类型
		return worker.DeserializeResult(sResult),
			nil
	}
}
